package com.backmanage.utils;


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.crypto.Cipher;

import sun.awt.image.ByteArrayImageSource;
public class RSAUtil {  
    public RSAUtil() {  
    }  
    
    private final static String PUBLIC_KEY="PublicKey";
    
    private final static String PRIVATE_KEY="PrivateKey";
    
    public static Map<String,Object> initKeyPairGenerator() throws Exception {  
    	
    	KeyPairGenerator generator =  KeyPairGenerator.getInstance("RSA");
    	
    	generator.initialize(1024);
    	
    	KeyPair keyPair = generator.generateKeyPair();
    	
    	RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
    	
    	RSAPrivateKey PrivateKey = (RSAPrivateKey) keyPair.getPrivate();
    	
    	Map<String,Object> map = new HashMap<String,Object>();
    	
    	map.put(PUBLIC_KEY, publicKey);
    	
    	map.put(PRIVATE_KEY, PrivateKey);
    	
    	return map;
    }
    /**
     * 加密
     * @param key
     * @param o 被加密数组
     * @return
     * @throws Exception
     */
    public static List<byte [] > encrypt(Key key,byte [] o) throws Exception {
    	
    	List<byte [] > list = new ArrayList<byte []>();
    	
    	Cipher cipher = Cipher.getInstance("RSA");
    	
    	cipher.init(Cipher.ENCRYPT_MODE, key);
    	
    	for (int i = 0; i <= o.length/117; i++) {
    		
        	byte [] b116 = Arrays.copyOfRange(o, i*117, (i+1)*117>=o.length?o.length:(i+1)*117);
        	
        	list.add(cipher.doFinal(b116));
		}
    	
    	return list;

    }
    /**
     * 要解密的数组
     * @param key
     * @param o
     * @return
     * @throws Exception
     */
    public static List<byte [] > decrypt(Key key,List<byte []> o) throws Exception {  
    	
    	List<byte [] > list = new ArrayList<byte []>();
    	
    	Cipher cipher = Cipher.getInstance("RSA");
    	
    	cipher.init(Cipher.DECRYPT_MODE, key);
    	
    	for (int i = 0; i < o.size(); i++) {
    		
        	list.add(cipher.doFinal(o.get(i)));
		}
    	
    	return list;
    }
    
	public static String byteArrayToHex(byte[] byteArray) {
		  char[] hexDigits = {'0','1','2','3','4','5','6','7','8','9', 'A','B','C','D','E','F' };
		  char[] resultCharArray =new char[byteArray.length * 2];
		  int index = 0;
		  for (byte b : byteArray) {
			  byte a=-1;
			  byte a1=1;
		     resultCharArray[index++] = hexDigits[(b>>> 4 )& 0xf];
		     resultCharArray[index++] = hexDigits[b& 0xf];
		  }
		  return new String(resultCharArray);
	}

	public static byte[] listToArray(List<byte []> b2) {
		
    	byte [] b3 = new byte [(b2.size()-1)*117+b2.get(b2.size()-1).length] ;
    	
    	int i = 0 ;
    	
    	for (byte[] cs : b2) {
    		System.arraycopy(cs, 0, b3, i*117,cs.length );
    		i++;
		}
		return b3;
	}
	
	private static byte[] ObjectToByte(Object o) throws IOException{
		
      	ByteArrayOutputStream bo = new ByteArrayOutputStream();  
      	
        ObjectOutputStream oo = new ObjectOutputStream(bo);  
        
        oo.writeObject(o);  
        
        return bo.toByteArray();
	}
	
	private static Object byteToObject(byte[] o) throws Exception{
		
		ByteArrayInputStream  bo = new ByteArrayInputStream (o);  
      	
		ObjectInputStream oo = new ObjectInputStream (bo);  
        
        return oo.readObject(); 
	}
    public static void main(String args[]) throws Exception {  

    	byte [] b = "/.;[].事故属于事故属于属于事故属于事故属于属于事故属于事故属于属于事故属于事故属于属1111111111qqqqqAAAAA>?/".getBytes();
    	
    	Map<String, Object> map = initKeyPairGenerator();

    	byte [] opub = ObjectToByte(map.get(PUBLIC_KEY));
    	
    	RSAPublicKey key =(RSAPublicKey) byteToObject(opub);
    	
    	List<byte []> b1 = encrypt(key, b);
    	
    	System.out.println("加密后的字符："+byteArrayToHex(listToArray(b1)));
    	
    	List<byte []> b2 = decrypt((Key)map.get(PRIVATE_KEY), b1);
    	
    	System.out.println("解密后的字符："+new String(listToArray(b2)));

    } 
    
    
}  
